﻿using DocumentFormat.OpenXml.Lite.Core.Interfaces;
using DocumentFormat.OpenXml.Lite.Core.Office;
using DocumentFormat.OpenXml.Lite.Shared;
using DocumentFormat.OpenXml.Lite.SpreadsheetML.Excel.Base;
using DocumentFormat.OpenXml.Lite.SpreadsheetML.Excel.WorksheetElements;
using DocumentFormat.OpenXml.Lite.Xml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using IO = System.IO;

namespace DocumentFormat.OpenXml.Lite.SpreadsheetML.Excel.Shared
{
    [XmlRoot("sst", Namespace = Constants.ExcelMain)]
    public class SharedStringTable : XmlSerializable, IOfficeElement, ISerializable
    {
        [XmlIgnore]
        public Guid DocumentId { get; set; }

        [Optional]
        [XmlAttribute("count")]
        public int Count { get; set; }

        [Optional]
        [XmlAttribute("uniqueCount")]
        public int UniqueCount { get; set; }

        [Optional]
        [XmlElement("", Namespace = Constants.ExcelMain)]
        public XmlList<StringItem> StringItems { get; set; }

        [Optional]
        [XmlElement("exLst")]
        public ExtensionList ExtensionList { get; set; }

        public SharedStringTable() 
        {
            StringItems = new XmlList<StringItem>();
            StringItems.Changing += StringItems_Changing;
        }

        void StringItems_Changing(object sender, ListEventArgs<StringItem> args)
        {
            if (args.Type == ListEventType.Add || args.Type == ListEventType.Insert)
            {
                UniqueCount++;
            }
            else if (args.Type == ListEventType.Remove)
            {
                UniqueCount--;
            }
        }

        public StringItem CreateSimpleStringItem(string text)
        {
            Count++;
            if (!StringItems.Any(i => i.Text.Value == text))
            {
                UniqueCount++;
            }
            StringItem item = new StringItem();
            item.Text = new SimpleText() { Value = text };
            StringItems.Add(item);
            return item;
        }

        #region ISerializable Members

        public byte[] Serialize()
        {
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("", Constants.ExcelMain);
            //ns.Add("xml", Constants.Xml);
            XmlSerializer serializer = new XmlSerializer(this.GetType());
            using (var stream = new IO.MemoryStream())
            {
                using (var writer = new IO.StreamWriter(stream, Encoding.UTF8))
                {
                    serializer.Serialize(writer, this, ns);
                    return stream.ToArray();
                }
            }
        }

        public void Deserialize(System.IO.Stream content)
        {
            XmlSerializer serializer = new XmlSerializer(this.GetType(), Constants.ExcelMain);
            var sst = serializer.Deserialize(content) as SharedStringTable;

            this.Count = sst.Count;
            this.ExtensionList = sst.ExtensionList;
            this.StringItems = sst.StringItems;
            this.UniqueCount = sst.UniqueCount;
        }

        #endregion
    }
}
